package com.yyj.service;

import com.alibaba.fastjson.JSONObject;
import com.yyj.common.ConfigReader;
import com.yyj.dao.TPropertyOwnerMapper;
import com.yyj.exception.BaseException;
import com.yyj.model.TPropertyManager;
import com.yyj.model.TPropertyOwner;
import com.yyj.model.TPropertyOwnerExample;
import com.yyj.pojo.MpAuthInfo;
import com.yyj.util.WXAppletUtil;
import com.yyj.util.WeixinUtil;
import com.yyj.util.security.MD5Util;
import com.yyj.web.protocol.req.*;
import com.yyj.web.protocol.resp.UserInfoResp;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class UserService {

    public static Logger log = LoggerFactory.getLogger(UserService.class);

    @Autowired
    ConfigReader configReader;

    @Autowired
    TPropertyOwnerMapper ownerMapper;

    @Autowired
    ManagerService managerService;

    @Transactional(rollbackFor = Exception.class)
    public UserInfoResp userSign(UserSignReq userSignReq){
        UserInfoResp ownerInfoResp = null;
        String password = userSignReq.getPassword();
        String rePassword = userSignReq.getRePassword();
        // TODO: 2018/11/1 前端密码加密字符解密，再做校验

        TPropertyOwner ownerObj = findOwnerByMobile(userSignReq.getMobile());
        if(null != ownerObj && StringUtils.isNotBlank(ownerObj.getRoomNum())){
            throw new BaseException("手机号已经存在");
        }

        if(!password.equals(rePassword)){
            throw new BaseException("两次输入密码不一致");
        }

        String openId = "wx-" + UUID.randomUUID().toString();
        TPropertyOwner owner = new TPropertyOwner();
        owner.setMobile(userSignReq.getMobile());
        owner.setOpenId(openId);
        owner.setRoomNum("");
        owner.setPassword(MD5Util.MD5(userSignReq.getPassword()));
        owner.setCreateTime(new Date());
        owner.setUpdateTime(new Date());
        owner.setStatus("VALID");
        int result = ownerMapper.insert(owner);
        if(1 == result){
            ownerInfoResp = new UserInfoResp();
            BeanUtils.copyProperties(owner , ownerInfoResp);
        }
        return ownerInfoResp;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserInfoResp initRoomNum(UserInitRoomReq userInitRoomReq){
        UserInfoResp ownerInfoResp = null ;
        TPropertyOwner ownerObj = findOwnerByMobile(userInitRoomReq.getMobile());
        if(null == ownerObj){
            throw new BaseException("手机号不存在");
        }
        if(StringUtils.isNotBlank(ownerObj.getRoomNum())){
            throw new BaseException("该手机已经绑定房号");
        }
        ownerObj.setRoomNum(userInitRoomReq.getRoomNum());
        ownerObj.setUpdateTime(new Date());
        int updateRlt = ownerMapper.updateByPrimaryKeySelective(ownerObj);
        if(1 == updateRlt){
            ownerInfoResp = new UserInfoResp();
            ownerInfoResp.setRoomNum(ownerObj.getRoomNum());
        }
        return ownerInfoResp;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserInfoResp initOwnerByAuth(WeixinAuthReq weixinAuthReq){
        log.info("initOwnerByAuth>>>>"+weixinAuthReq.toString());
        UserInfoResp userInfoResp = new UserInfoResp();
        String appId = configReader.getAppId();
        String appSecret = configReader.getAppSecret();
        MpAuthInfo mpAuthInfo = WeixinUtil.getMpAuthInfo(appId , appSecret , weixinAuthReq.getCode());
        if(null == mpAuthInfo){
            throw new BaseException("获取用户openId失败");
        }
        String openId = mpAuthInfo.getOpenId();
        TPropertyOwner ownerInfo = findOwnerByOpenId(openId);
        if(null != ownerInfo){
            if(!"VALID".equals(ownerInfo.getStatus())){
                throw new BaseException("用户状态不可用");
            }
            userInfoResp.setAdmin(false);
            userInfoResp.setRoomNum(ownerInfo.getRoomNum());
        }else{
            JSONObject wxUserInfo = WXAppletUtil.getUserInfo(weixinAuthReq.getEncryptedData() , mpAuthInfo.getSessionKey() , weixinAuthReq.getIv());
            String phoneNumber = "";
            log.info("wxUserInfo:{}" , wxUserInfo.toJSONString());
            if(null != wxUserInfo){
                phoneNumber = wxUserInfo.getString("phoneNumber");
            }

            TPropertyManager propertyManager = managerService.findManagerByMobile(phoneNumber);
            if( null != propertyManager ){
                userInfoResp.setOpenId(propertyManager.getOpenId());
                userInfoResp.setMobile(propertyManager.getMobile());
                userInfoResp.setUserId(propertyManager.getId());
                userInfoResp.setAdmin(true);
                return  userInfoResp;
            }else{
                //根据手机号查询业主，替换openId
                TPropertyOwner ownerObj = findOwnerByMobile(phoneNumber);
                if(null != ownerObj){
                    ownerObj.setOpenId(openId);
                    ownerObj.setUpdateTime(new Date());
                    ownerMapper.updateByPrimaryKeySelective(ownerObj);
                    ownerInfo = ownerObj;
                }else{
                    TPropertyOwner propertyOwner = new TPropertyOwner();
                    propertyOwner.setOpenId(openId);
                    propertyOwner.setMobile(phoneNumber);
                    propertyOwner = addPropertyOwner(propertyOwner);
                    ownerInfo = propertyOwner;
                }
                userInfoResp.setRoomNum(ownerInfo.getRoomNum());
                userInfoResp.setAdmin(false);
            }
        }
        userInfoResp.setUserId(ownerInfo.getId());
        userInfoResp.setOpenId(ownerInfo.getOpenId());
        userInfoResp.setMobile(ownerInfo.getMobile());
        return userInfoResp;
    }

    public TPropertyOwner findOwnerByMobile(String mobile){
        TPropertyOwnerExample ownerExample = new TPropertyOwnerExample();
        TPropertyOwnerExample.Criteria criteria = ownerExample.createCriteria();
        criteria.andMobileEqualTo(mobile);
        List<TPropertyOwner> ownerList = ownerMapper.selectByExample(ownerExample);
        if(ownerList != null && ownerList.size() > 0){
            return ownerList.get(0);
        }else{
            return null;
        }
    }

    public TPropertyOwner findOwnerByOpenId(String openId){
        TPropertyOwnerExample ownerExample = new TPropertyOwnerExample();
        TPropertyOwnerExample.Criteria criteria = ownerExample.createCriteria();
        criteria.andOpenIdEqualTo(openId);
        List<TPropertyOwner> ownerList = ownerMapper.selectByExample(ownerExample);
        if(ownerList != null && ownerList.size() > 0){
            return ownerList.get(0);
        }else{
            return null;
        }
    }

    public TPropertyOwner findOwnerByMobile(String mobile , String roomNum){
        TPropertyOwnerExample ownerExample = new TPropertyOwnerExample();
        TPropertyOwnerExample.Criteria criteria = ownerExample.createCriteria();
        criteria.andMobileEqualTo(mobile);
        criteria.andRoomNumEqualTo(roomNum);
        List<TPropertyOwner> ownerList = ownerMapper.selectByExample(ownerExample);
        if(ownerList != null && ownerList.size() > 0){
            return ownerList.get(0);
        }else{
            return null;
        }
    }

    public List<TPropertyOwner> findOwnersByRoomNum(String roomNum){
        TPropertyOwnerExample ownerExample = new TPropertyOwnerExample();
        TPropertyOwnerExample.Criteria criteria = ownerExample.createCriteria();
        criteria.andRoomNumEqualTo(roomNum);
        List<TPropertyOwner> ownerList = ownerMapper.selectByExample(ownerExample);
        return ownerList;
    }

    public TPropertyOwner addPropertyOwner(TPropertyOwner propertyOwner){
        propertyOwner.setCreateTime(new Date());
        propertyOwner.setUpdateTime(new Date());
        propertyOwner.setStatus("VALID");
        ownerMapper.insert(propertyOwner);
        return propertyOwner;
    }

    @Transactional(rollbackFor = Exception.class)
    public UserInfoResp userLogin(UserLoginReq userLoginReq) {
        UserInfoResp userInfoResp = null;
        String mobile = userLoginReq.getMobile();
        String password = userLoginReq.getPassword();
        String userPass = MD5Util.MD5(password);
        TPropertyOwner ownerObj = findOwnerByMobile(mobile);
        if(null != ownerObj){
            if(!"VALID".equals(ownerObj.getStatus())){
                throw new BaseException("用户状态不可用");
            }
            if(!userPass.equals(ownerObj.getPassword())){
                throw new BaseException("密码错误");
            }
            userInfoResp = new UserInfoResp();
            userInfoResp.setAdmin(false);
            userInfoResp.setMobile(ownerObj.getMobile());
            userInfoResp.setRoomNum(ownerObj.getRoomNum());
            userInfoResp.setOpenId(ownerObj.getOpenId());
            userInfoResp.setIsRoot(0);

        }else{
            TPropertyManager propertyManager = managerService.findManagerByMobile(mobile);
            if(null == propertyManager){
                throw new BaseException("用户不存在");
            }
            if(!"VALID".equals(propertyManager.getStatus())){
                throw new BaseException("管理员状态不可用");
            }
            if(!userPass.equals(propertyManager.getPassword())){
                throw new BaseException("密码错误");
            }
            userInfoResp = new UserInfoResp();
            userInfoResp.setAdmin(true);
            userInfoResp.setMobile(propertyManager.getMobile());
            userInfoResp.setOpenId(propertyManager.getOpenId());
            userInfoResp.setIsRoot(propertyManager.getIsRoot());
        }

        return userInfoResp;
    }



    @Transactional(rollbackFor = Exception.class)
    public UserInfoResp testAuth(String mobile ,  String openId){
        log.info("testAuth>>>>mobile:"+mobile);
        log.info("testAuth>>>>openId:"+openId);
        UserInfoResp userInfoResp = new UserInfoResp();
        TPropertyOwner ownerInfo = findOwnerByOpenId(openId);
        if(null != ownerInfo){
            if(!"VALID".equals(ownerInfo.getStatus())){
                throw new BaseException("用户状态不可用");
            }
            userInfoResp.setAdmin(false);
            userInfoResp.setRoomNum(ownerInfo.getRoomNum());
        }else{
            TPropertyManager propertyManager = managerService.findManagerByMobile(mobile);
            if( null != propertyManager ){
                userInfoResp.setOpenId(propertyManager.getOpenId());
                userInfoResp.setMobile(propertyManager.getMobile());
                userInfoResp.setUserId(propertyManager.getId());
                userInfoResp.setAdmin(true);
                return  userInfoResp;
            }else{
                //根据手机号查询业主，替换openId
                TPropertyOwner ownerObj = findOwnerByMobile(mobile);
                if(null != ownerObj){
                    ownerObj.setOpenId(openId);
                    ownerObj.setUpdateTime(new Date());
                    ownerMapper.updateByPrimaryKeySelective(ownerObj);
                    ownerInfo = ownerObj;
                }else{
                    TPropertyOwner propertyOwner = new TPropertyOwner();
                    propertyOwner.setOpenId(openId);
                    propertyOwner.setMobile(mobile);
                    propertyOwner = addPropertyOwner(propertyOwner);
                    ownerInfo = propertyOwner;
                }
                userInfoResp.setRoomNum(ownerInfo.getRoomNum());
                userInfoResp.setAdmin(false);
            }
        }
        userInfoResp.setUserId(ownerInfo.getId());
        userInfoResp.setOpenId(ownerInfo.getOpenId());
        userInfoResp.setMobile(ownerInfo.getMobile());

        return userInfoResp;
    }

    @Transactional(rollbackFor = Exception.class)
    public void addOwner(OwnerAddReq ownerAddReq) throws Exception{
        String password = ownerAddReq.getPassword();
        String rePassword = ownerAddReq.getRePassword();
        TPropertyOwner ownerObj = findOwnerByMobile(ownerAddReq.getMobile());
        if (null != ownerObj) {
            throw new BaseException("业主已存在");
        }
        if (!password.equals(rePassword)) {
            throw new BaseException("两次输入密码不一致");
        }
        ownerObj = new TPropertyOwner();
        ownerObj.setMobile(ownerAddReq.getMobile());
        ownerObj.setPassword(MD5Util.MD5(password));
        ownerObj.setStatus("VALID");
        ownerObj.setRoomNum(ownerAddReq.getRoomNum());
        ownerObj.setCreateTime(new Date());
        ownerObj.setUpdateTime(new Date());
        ownerMapper.insert(ownerObj);

    }

    @Transactional(rollbackFor = Exception.class)
    public void updateOwner(String mobile , OwnerUpdateReq ownerUpdateReq) {
        String password = ownerUpdateReq.getPassword();
        String rePassword = ownerUpdateReq.getRePassword();
        TPropertyOwner ownerObj = findOwnerByMobile(mobile);
        if (null == ownerObj) {
            throw new BaseException("业主不存在");
        }
        if (!"VALID".equals(ownerObj.getStatus())) {
            throw new BaseException("业主状态为禁用");
        }

        if (!password.equals(rePassword)) {
            throw new BaseException("两次输入密码不一致");
        }
        ownerObj.setMobile(ownerUpdateReq.getMobile());
        ownerObj.setPassword(MD5Util.MD5(password));
        ownerObj.setUpdateTime(new Date());
        ownerMapper.updateByPrimaryKeySelective(ownerObj);

    }

    @Transactional(rollbackFor = Exception.class)
    public void updateOwnerStatus(UserStatusUpdateReq userStatusUpdateReq) throws Exception{
        TPropertyOwner propertyManager = ownerMapper.selectByPrimaryKey(userStatusUpdateReq.getId());
        propertyManager.setStatus(userStatusUpdateReq.getStatus());
        propertyManager.setUpdateTime(new Date());
        ownerMapper.updateByPrimaryKeySelective(propertyManager);
    }




}
